package com.kingsoft.miot.bridge.controller;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.kingsoft.miot.bridge.common.CommonResult;
import com.kingsoft.miot.bridge.common.Roles;
import com.kingsoft.miot.bridge.controller.tmp.DeviceBrief;
import com.kingsoft.miot.bridge.controller.tmp.TimePeriod;
import com.kingsoft.miot.bridge.pojo.hotel.HotelArea;
import com.kingsoft.miot.bridge.pojo.hotel.HotelInfo;
import com.kingsoft.miot.bridge.pojo.manager.GroupInfo;
import com.kingsoft.miot.bridge.pojo.pub.AreaInfo;
import com.kingsoft.miot.bridge.service.AreaService;
import com.kingsoft.miot.bridge.service.HotelService;
import com.kingsoft.miot.bridge.service.manager.GroupInfoService;
import com.kingsoft.miot.bridge.utils.AESCrypto;

/**
 * 公共类接口
 * 
 * @author HUJIANQING
 *
 */
@RestController
public class PublicController extends BaseController {

	private static final Logger LOGGER = LoggerFactory.getLogger(PublicController.class);

	@Autowired
	private HotelService hotelSerivce;
	// 角色
	@Autowired
	private GroupInfoService groupInfoService;
	// 区域列表
	@Autowired
	private AreaService areaService;
//	@Autowired
//	private ManagerService managerService;

	/**
	 * 返回区域列表
	 * 
	 * @return
	 */
	@RequestMapping(value = "/data/common/area", produces = "text/html; charset=UTF-8")
	public String getAreaList() {
		List<HotelArea> retList = new ArrayList<>();
//		HotelArea hotelArea1 = new HotelArea();
//		hotelArea1.setName("华北地区");
//		hotelArea1.setValue(1);
//		HotelArea hotelArea2 = new HotelArea();
//		hotelArea1.setName("华南地区");
//		hotelArea1.setValue(2);
//		HotelArea hotelArea3 = new HotelArea();
//		hotelArea1.setName("华中地区");
//		hotelArea1.setValue(3);
//		HotelArea hotelArea4 = new HotelArea();
//		hotelArea1.setName("华东地区");
//		hotelArea1.setValue(4);
//		areaList.add(hotelArea1);
//		areaList.add(hotelArea2);
//		areaList.add(hotelArea3);
//		areaList.add(hotelArea4);
//		return JSON.toJSONString(areaList);
		try {
			List<AreaInfo> areaList = areaService.getAll();
			if (areaList == null) {
				return CommonResult.returnJson(false, 400, "获取区域信息失败");
			}
			for (AreaInfo areaInfo : areaList) {
				HotelArea hotelArea = new HotelArea();
				hotelArea.setName(areaInfo.getArea_info_name());
				hotelArea.setValue(areaInfo.getArea_info_id());
				retList.add(hotelArea);
			}
			return JSON.toJSONString(retList);
		} catch (Exception e) {
			LOGGER.info("获取区域信息失败。");
			return CommonResult.returnJson(false, 500, "获取区域信息失败。");
		}

	}

	/**
	 * 返回时区
	 * 
	 * @return
	 */

	@RequestMapping(value = "/data/common/time_period", produces = "text/html; charset=UTF-8")
	public String getTime_period() {
		TimePeriod p1 = new TimePeriod();
		p1.setName("今日");
		p1.setValue(0);
		TimePeriod p2 = new TimePeriod();
		p2.setName("昨天");
		p2.setValue(1);
		TimePeriod p3 = new TimePeriod();
		p3.setName("前天");
		p3.setValue(2);
		TimePeriod p4 = new TimePeriod();
		p4.setName("后天");
		p4.setValue(3);
		TimePeriod p5 = new TimePeriod();
		p5.setName("星期天");
		p5.setValue(4);
		List<TimePeriod> timePeriodList = new ArrayList<>();
		timePeriodList.add(p1);
		timePeriodList.add(p2);
		timePeriodList.add(p3);
		timePeriodList.add(p4);
		timePeriodList.add(p5);
		return JSON.toJSONString(timePeriodList);
	}

	/**
	 * 获取角色列表 指当前用户权限下能获取的角色列表
	 * 
	 * @return
	 */
	@RequiresRoles(value = { "all_manager", "chief_manager", "area_manager", "hotel_manager" }, logical = Logical.OR)
	@RequestMapping(value = "/data/common/level", method = RequestMethod.GET, produces = "text/html; charset=UTF-8")
	public String getLeve() {

		// 返回记录
		List<Map<String, Object>> retData = new ArrayList<>();
		try {
			// 所有角色
			List<GroupInfo> groupInfoList = groupInfoService.findAll();
			// 判断当前账户拥有
			Subject subject = SecurityUtils.getSubject();
			/**
			 * 1. 判断是上帝权限 获取所有 角色 包括 all_manager
			 */
			try {
				// 检测是否拥有创建管理员的权限 这玩意干嘛非得抛异常
				subject.checkRole(Roles.ALL_MANAGER);
				// 检测成功 返回所有角色
				for (GroupInfo groupInfo : groupInfoList) {
					Map<String, Object> item = new HashMap<>();
					item.put("name", groupInfo.getGroup_info_name());
					item.put("value", groupInfo.getGroup_info_id());
					retData.add(item);
				}
				return CommonResult.jsonString(retData);
			} catch (Exception e) {
				// 吞了
			}
			/**
			 * 2. 判断是集团管理员权限 可查看 区域经理 和 酒店经理 不能查看 普通员工 和 上帝
			 */
			setRetRoles(retData, subject, Roles.CHEIF_MANAGER, new String[] { Roles.AREA_MANAGER, Roles.HOTEL_MANAGER },
					groupInfoList);
			/**
			 * 3. 判断是区域管理员权限 可查看 酒店经理 和 普通员工 不能查看 区域经理 和 上帝
			 */
			setRetRoles(retData, subject, Roles.AREA_MANAGER,
					new String[] { Roles.HOTEL_MANAGER, Roles.ORDINARY_MANAGER }, groupInfoList);
			/**
			 * 4. 判断是否为酒店 经理 只能普通员工 其他不能查询
			 */
			setRetRoles(retData, subject, Roles.HOTEL_MANAGER, new String[] { Roles.ORDINARY_MANAGER }, groupInfoList);
			LOGGER.info("查询角色信息列表成功。");
			// 最低打印
			retData.forEach( x -> System.out.println(JSON.toJSONString(x)));
			return CommonResult.jsonString(retData);
		} catch (Exception e) {
			LOGGER.error("返回角色列表失败。");
			return CommonResult.returnJson(false, 400, "返回角色列表失败。");
		}
	}

	/**
	 * 获取设备列表
	 * 
	 * @return
	 */
	@RequestMapping(value = "/data/common/devices", produces = "text/html; charset=UTF-8")
	public String getDevices() {
		DeviceBrief device1 = new DeviceBrief();
		device1.setName("空调");
		device1.setValue(2);
		DeviceBrief device2 = new DeviceBrief();
		device2.setName("智能音箱");
		device2.setValue(3);
		DeviceBrief device3 = new DeviceBrief();
		device3.setName("智能灯");
		device3.setValue(5);
		List<DeviceBrief> deviceList = new ArrayList<>();
		deviceList.add(device1);
		deviceList.add(device2);
		deviceList.add(device3);
		return JSON.toJSONString(deviceList);
	}

	/**
	 * 获取所有的酒店 即当前用户下的所有酒店
	 * 
	 * @return
	 */
	@RequestMapping(value = "/data/common/hotels", produces = "text/html; charset=UTF-8")
	public String getHotels(HttpServletRequest httpServletRequest) {
		// 0. IAM权限系统校验
		List<Map<String, Object>> hotelList = null;
		try {
			/**
			 * 1.使用session 判断是否为当前回话登录的用户 // 这里应放到拦截器中
			 */
//			if (getAccess(httpServletRequest, id) == null) {
//				LOGGER.error("非前登录用户，无法获取信息列表");
//				return CommonResult.returnJson(false, 400, "非前登录用户，无法获取信息列表");
//			}

			// 需要鉴权
			List<HotelInfo> list = hotelSerivce.findAll();
			hotelList = new ArrayList<>();
			for (HotelInfo info : list) {
				Map<String, Object> dataMap = new HashMap<String, Object>();
				dataMap.put("name", info.getHotel_info_name());
				dataMap.put("value", info.getHotel_info_id());
				hotelList.add(dataMap);
			}
			return JSON.toJSONString(hotelList);

//			ManagerGroupRecord record = managerGroupRecordService.getByManagerId(Integer.valueOf(id));
//			Set<String> authUnitIdSet = new HashSet<String>();
//			// 1. 判断是否为超级用户 如果是则跳过2 3 ,并 直接获取所有的Auth unit id 的room
//			boolean isSuperFlag = false;
//			if ("集团管理员".equals(record.getGroup_info_name())) {
//				isSuperFlag = true;
//			}
//			Set<Integer> hotelIdList = new HashSet<Integer>();
//			// hotel list
//			if (!isSuperFlag) { // 2.获取当前用户的所拥有的酒店id
//				List<ManagerHotelRecord> ManagerHotelRecordList = managerHotelRecordService
//						.getManagerHotelRecordByManagerId(Integer.valueOf(id));
//				Set<Integer> hoteIdList = new HashSet<>();
//				ManagerHotelRecordList.forEach(x -> hoteIdList.add(x.getHotel_info_id()));
//				// 3. 如果是具有区域控制权限的使用者 则获取该区域下所有的酒店id 并合并 hoteIdList的所有ID
//				// 3.1 获取酒店管理者的区域
//				AreaManagerRecord areaManagerRecord = areaManagerRecordService
//						.getAreaManagerRecordByManagerId(Integer.valueOf(id)); 
//				// 3.2 获取区域相关的酒店
//				List<AreaHotelRecord> areaHotelRecordList = areaHotelRecordService
//						.getAreaHotelRecordByAreaId(areaManagerRecord.getArea_info_id());
//				areaHotelRecordList.forEach(x -> hoteIdList.add(x.getHotel_info_id()));
//				// 4. 通过List查询所有酒店
//				hotelIdList = hotelSerivce.selectByHotelIdList(hoteIdList);
//			}
//			// 如果是超级管理员则获取所有相关的hotel
//			if (isSuperFlag) {
//
//			}
//
//			// 批量查询set hotelSerivce.getByAuthUnitId(authUnitIdSet);
//			// 1.获取当前用户的所拥有的酒店id
//			List<ManagerHotelRecord> ManagerHotelRecordList = managerHotelRecordService
//					.getManagerHotelRecordByManagerId(Integer.valueOf(id));
//			ManagerHotelRecordList.forEach(x -> hotelIdList.add(x.getHotel_info_id()));
//			// 2. 批量查询所有的酒店
//			hotelList = hotelSerivce.getByHotelIdList(hotelIdList);
		} catch (Exception e) {
			LOGGER.error("无法获取信息列表");
			return CommonResult.returnJson(false, 400, "无法获取信息列表");
		}
//		return JSON.toJSONString(hotelList);
	}

	/**
	 * 检测角色是否拥有该权限 并 返回需要的角色信息
	 * 
	 * @param retData
	 * @param subject
	 * @param check
	 * @param needRoles 需要的角色
	 * @return
	 */
	private void setRetRoles(List<Map<String, Object>> retData, Subject subject, String check, final String[] needRoles,
			List<GroupInfo> groupInfoList) {
		try {
			if (retData == null || needRoles == null || needRoles.length <= 0) {
				return;
			}
			// 检测 并过滤信息 检测是否拥有创建管理员的权限 这玩意干嘛非得抛异常
			subject.checkRole(check);
			for (GroupInfo groupInfo : groupInfoList) {
				for (String role : needRoles) {
					if (role.equals(groupInfo.getGroup_info_code())) {
						Map<String, Object> item = new HashMap<>();
						item.put("name", groupInfo.getGroup_info_name());
						item.put("value", groupInfo.getGroup_info_id());
						retData.add(item);
					}
				}
			}
		} catch (Exception e) {
			return;
		}
	}

	/**
	 * 是否能得到允许
	 * 
	 * @param httpServletRequest
	 * @param id
	 * @return
	 */
	private Object getAccess(HttpServletRequest httpServletRequest, String id) {
		HttpSession session = getSession(httpServletRequest);
		try {
			return session.getAttribute(AESCrypto.cipher(id));
		} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | UnsupportedEncodingException
				| IllegalBlockSizeException | BadPaddingException e) {
			return null;
		}
	}
}
